--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Commit 3f0d91ecdbb0b5ef2e85a2a8ff596fdd2c11e853
Parents : dfac5cb
Author : Mark Qvist <mark@unsigned.io>
Date : 2025-10-28T12:33:06+01:00
Fixed Android BLE stack re-connection hang for RNodeInterface
Changes
2 files changed, 31 insertions(+), 28 deletions(-)
Diff
diff --git a/sbapp/services/sidebandservice.py b/sbapp/services/sidebandservice.py
index 814c2b6b..f76ccb6a 100644
--- a/sbapp/services/sidebandservice.py
+++ b/sbapp/services/sidebandservice.py
@@ -229,6 +229,8 @@ class SidebandService():
self.notification_intent = None
self.notification_small_icon = None
+ self.rnode_ble_reset_required = False
+
if RNS.vendor.platformutils.is_android():
self.android_service = autoclass('org.kivy.android.PythonService').mService
self.app_context = self.android_service.getApplication().getApplicationContext()
@@ -476,6 +478,15 @@ class SidebandService():
self.sideband.setstate("wants.settings_reload", False)
self.sideband.reload_configuration()
+ if self.sideband.getstate("wants.rnode_ble_reset"):
+ self.sideband.setstate("wants.rnode_ble_reset", False)
+ RNS.log("RNode BLE hardware error detected, re-initializing Android BLE dispatcher", RNS.LOG_ERROR)
+ if hasattr(self.sideband, "interface_rnode") and self.sideband.interface_rnode != None:
+ self.sideband.interface_rnode.reset_ble()
+ RNS.log("BLE hardware reset executed", RNS.LOG_INFO)
+ else:
+ RNS.log("No RNode interface active, could not execute BLE hardware reset", RNS.LOG_ERROR)
+
time.sleep(sleep_time)
self.sideband.cleanup()
diff --git a/sbapp/sideband/core.py b/sbapp/sideband/core.py
index 8fa432c3..91c88f89 100644
--- a/sbapp/sideband/core.py
+++ b/sbapp/sideband/core.py
@@ -105,20 +105,20 @@ class PropagationNodeDetector():
self.owner_app = owner.owner_app
class SidebandCore():
- CONV_P2P = 0x01
- CONV_GROUP = 0x02
- CONV_BROADCAST = 0x03
- CONV_VOICE = 0x04
+ CONV_P2P = 0x01
+ CONV_GROUP = 0x02
+ CONV_BROADCAST = 0x03
+ CONV_VOICE = 0x04
- MAX_ANNOUNCES = 24
+ MAX_ANNOUNCES = 24
- SERVICE_JOB_INTERVAL = 1
- PERIODIC_JOBS_INTERVAL = 60
- PERIODIC_SYNC_RETRY = 360
- TELEMETRY_KEEP = 60*60*24*7
- TELEMETRY_INTERVAL = 60
- SERVICE_TELEMETRY_INTERVAL = 300
- TELEMETRY_CLEAN_INTERVAL = 3600
+ SERVICE_JOB_INTERVAL = 1
+ PERIODIC_JOBS_INTERVAL = 60
+ PERIODIC_SYNC_RETRY = 360
+ TELEMETRY_KEEP = 60*60*24*7
+ TELEMETRY_INTERVAL = 60
+ SERVICE_TELEMETRY_INTERVAL = 300
+ TELEMETRY_CLEAN_INTERVAL = 3600
IF_CHANGE_ANNOUNCE_MIN_INTERVAL = 3.5 # In seconds
AUTO_ANNOUNCE_RANDOM_MIN = 90 # In minutes
@@ -128,6 +128,8 @@ class SidebandCore():
LOG_DEQUE_MAXLEN = 128
+ ERROR_INVALID_BLE_MTU = 0x20
+
aspect_filter = "lxmf.delivery"
def received_announce(self, destination_hash, announced_identity, app_data, announce_packet_hash):
# Add the announce to the directory announce
@@ -139,7 +141,7 @@ class SidebandCore():
"q": self.reticulum.get_packet_q(announce_packet_hash)}
# This reformats the new v0.5.0 announce data back to the expected format
- # for Sidebands database and other handling functions.
+ # for Sideband's database and other handling functions.
dn = LXMF.display_name_from_app_data(app_data)
sc = LXMF.stamp_cost_from_app_data(app_data)
app_data = b""
@@ -3580,22 +3582,12 @@ class SidebandCore():
if hasattr(self, "interface_rnode") and self.interface_rnode != None:
if len(self.interface_rnode.hw_errors) > 0:
- self.setpersistent("runtime.errors.rnode", self.interface_rnode.hw_errors[0])
- self.interface_rnode.hw_errors = []
+ if self.interface_rnode.hw_errors[0]["error"] == self.ERROR_INVALID_BLE_MTU:
+ self.setstate("wants.rnode_ble_reset", True)
+ else:
+ self.setpersistent("runtime.errors.rnode", self.interface_rnode.hw_errors[0])
- # if not self.interface_rnode_adding:
- # RNS.log("Hardware error on RNodeInterface, scheduling re-init", RNS.LOG_DEBUG)
- # if self.interface_rnode in RNS.Transport.interfaces:
- # RNS.Transport.interfaces.remove(self.interface_rnode)
- # del self.interface_rnode
- # self.interface_rnode = None
- # self.interface_rnode_adding = True
- # def job():
- # self.__add_rnodeinterface(delay=5)
- # if self.config["start_announce"] == True:
- # time.sleep(12)
- # self.lxmf_announce(attached_interface=self.interface_rnode)
- # threading.Thread(target=job, daemon=True).start()
+ self.interface_rnode.hw_errors = []
if (now - last_multicast_lock_check > 120):
RNS.log("Checking multicast and wake locks", RNS.LOG_DEBUG)
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────